package link.chengguo.orangemall.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import link.chengguo.orangemall.bo.Tree;
import link.chengguo.orangemall.enums.AllEnum;
import link.chengguo.orangemall.sys.entity.SysPermission;
import link.chengguo.orangemall.sys.entity.SysPermissionNode;
import link.chengguo.orangemall.sys.mapper.SysPermissionMapper;
import link.chengguo.orangemall.sys.service.ISysPermissionService;
import link.chengguo.orangemall.sys.service.ISysUserService;
import link.chengguo.orangemall.ums.service.RedisService;
import link.chengguo.orangemall.util.BuildTree;
import link.chengguo.orangemall.util.JsonUtil;
import link.chengguo.orangemall.util.UserUtils;
import link.chengguo.orangemall.utils.ValidatorUtils;
import link.chengguo.orangemall.vo.Rediskey;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 后台用户权限表 服务实现类
 * </p>
 *
 * @author chengguo
 * @since 2019-04-14
 */
@Service
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements ISysPermissionService {

    @Resource
    private SysPermissionMapper permissionMapper;
    @Resource
    private ISysUserService userService;

    @Resource
    private RedisService redisService;

    @Override
    public List<Tree<SysPermission>> getAllPermission() {
        List<Tree<SysPermission>> trees = Lists.newArrayList();
        List<SysPermission> menuDOs = new ArrayList<>();

        if (UserUtils.getCurrentMember().getPlatform().equals(AllEnum.PlatformType.Tenant.code())){
            if (!redisService.exists(String.format(Rediskey.allTreesList, "admin"))) {
                List<Long> types = Lists.newArrayList(1L, 0L);
                QueryWrapper queryWrapper=new QueryWrapper();
                queryWrapper.eq("status", 1);
                queryWrapper.eq("platform",AllEnum.PlatformType.Tenant.code());
                queryWrapper.in("type", types);
                queryWrapper.orderByAsc("sort");
                menuDOs = permissionMapper.selectList(queryWrapper);
                redisService.set(String.format(Rediskey.allTreesList, "admin"), JsonUtil.objectToJson(menuDOs));
            } else {
                menuDOs = JsonUtil.jsonToList(redisService.get(String.format(Rediskey.allTreesList, "admin")), SysPermission.class);
            }
        }else if(UserUtils.getCurrentMember().getPlatform().equals(AllEnum.PlatformType.Agent.code())){
            if (!redisService.exists(String.format(Rediskey.allTreesList2, "agent"))) {
                List<Long> types = Lists.newArrayList(1L, 0L);
                QueryWrapper queryWrapper=new QueryWrapper();
                queryWrapper.eq("status", 1);
                queryWrapper.eq("platform",AllEnum.PlatformType.Agent.code());
                queryWrapper.in("type", types);
                queryWrapper.orderByAsc("sort");
                menuDOs = permissionMapper.selectList(queryWrapper);
                redisService.set(String.format(Rediskey.allTreesList2, "agent"), JsonUtil.objectToJson(menuDOs));
            } else {
                menuDOs = JsonUtil.jsonToList(redisService.get(String.format(Rediskey.allTreesList2, "agent")), SysPermission.class);
            }
        }
        if (menuDOs != null && menuDOs.size() > 0) {
            for (SysPermission sysMenuDO : menuDOs) {
                Tree<SysPermission> tree = new Tree<SysPermission>();
                tree.setId(sysMenuDO.getId().toString());
                if (ValidatorUtils.notEmpty(sysMenuDO.getPid())){
                    tree.setParentId(sysMenuDO.getPid().toString());
                }

                tree.setTitle(sysMenuDO.getName());
                Map<String, Object> attributes = new HashMap<>(16);
                attributes.put("url", sysMenuDO.getUri());
                attributes.put("component", sysMenuDO.getComponent());
                attributes.put("icon", sysMenuDO.getIcon());
                tree.setMeta(attributes);
                trees.add(tree);
            }
            // 默认顶级菜单为０，根据数据库实际情况调整
            List<Tree<SysPermission>> list = BuildTree.buildList(trees, "0");
            return list;
        }
        return new ArrayList<>();
    }

    @Override
    public Map<String,Object> removeRoleById(Long id) {
        List<Long> deleteIds = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        finSubNode(deleteIds,id);
        if(deleteIds.size()>1){
            map.put("subNodeExist",true);
            map.put("deleteIds",deleteIds);
        }else {
            this.removeById(id);
            map.put("subNodeExist", false);
        }
        return map;
    }

    private void finSubNode(List<Long> deleteIds,Long id) {
        //能传进来意味着该id存在，先添加进删除列表
        deleteIds.add(id);
        //查询以该id为pid的权限
        SysPermission sysPermission = new SysPermission();
        sysPermission.setPid(id);
        List<SysPermission> sysPermissions = permissionMapper.selectList(new QueryWrapper<>(sysPermission));
        if(!ValidatorUtils.isEmpty(sysPermission)){
            for(SysPermission sysPermission1:sysPermissions){
                finSubNode(deleteIds,sysPermission1.getId());
            }
        }

    }


    @Override
    public List<Tree<SysPermission>> getPermissionsByUserId(Long id) {
        List<Tree<SysPermission>> trees = Lists.newArrayList();
        List<SysPermission> menuDOs = userService.listMenuByUserId(id);
        for (SysPermission sysMenuDO : menuDOs) {
            Tree<SysPermission> tree = new Tree<SysPermission>();
            tree.setId(sysMenuDO.getId().toString());
            tree.setParentId(sysMenuDO.getPid().toString());
            tree.setTitle(sysMenuDO.getName());
            Map<String, Object> attributes = new HashMap<>(16);
            attributes.put("url", sysMenuDO.getUri());
            attributes.put("component", sysMenuDO.getComponent());
            attributes.put("icon", sysMenuDO.getIcon());
            tree.setMeta(attributes);
            trees.add(tree);
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        List<Tree<SysPermission>> list = BuildTree.buildList(trees, "0");
        return list;
    }

    @Override
    public List<SysPermissionNode> treeList() {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("platform", UserUtils.getCurrentMember().getPlatform());
        queryWrapper.orderByAsc("sort");
        List<SysPermission> permissionList = permissionMapper.selectList(queryWrapper);
        List<SysPermissionNode> result = permissionList.stream()
                .filter(permission -> permission.getPid().equals(0L))
                .map(permission -> covert(permission, permissionList)).collect(Collectors.toList());
        return result;
    }

    public int updateShowStatus(List<Long> ids, Integer showStatus) {
        SysPermission productCategory = new SysPermission();
        productCategory.setStatus(showStatus);
        return permissionMapper.update(productCategory, new QueryWrapper<SysPermission>().in("id", ids));

    }

    /**
     * 将权限转换为带有子级的权限对象
     * 当找不到子级权限的时候map操作不会再递归调用covert
     */
    private SysPermissionNode covert(SysPermission permission, List<SysPermission> permissionList) {
        SysPermissionNode node = new SysPermissionNode();
        BeanUtils.copyProperties(permission, node);
        List<SysPermissionNode> children = permissionList.stream()
                .filter(subPermission -> subPermission.getPid().equals(permission.getId()))
                .map(subPermission -> covert(subPermission, permissionList)).collect(Collectors.toList());
        node.setChildren(children);
        return node;
    }
}
